package com.example.monitor.util.redis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.Jedis;

public class RedisTemplate {

	private static RedisTemplate redisTemplate;

	private RedisTemplate() {

	}

	/**
	 * 加载默认redis配置文件
	 * 
	 * @return
	 */
	public static RedisTemplate getRedisHelp() {
		if (redisTemplate == null) {
			synchronized (RedisTemplate.class) {
				if (redisTemplate == null) {
					redisTemplate = new RedisTemplate();
				}
			}
		}
		return redisTemplate;
	}

	// //////////////操作字符串//////////////////////
	/**
	 * 存储key(字符串)
	 * 
	 * @param key
	 * @param obj
	 */
	public boolean SaveString(String key, String value) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.append(key, value);
			} else {
				jedis.set(key, value);
			}
		} catch (Exception e) {
			System.err.println("存储key(字符串)出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 存储key
	 * 
	 * @param key
	 * @param value
	 * @param time
	 *            （设置过期时间）
	 */
	public boolean SaveString(String key, String value, int time) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			jedis.setex(key, time, value);
		} catch (Exception e) {
			System.err.println("存储key出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 获取key对应-value
	 * 
	 * @param key
	 * @return
	 */
	public String getStringValue(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				return jedis.get(key);
			}
		} catch (Exception e) {
			System.err.println("获取key对应-value出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return null;
	}

	/**
	 * 删除数据
	 * 
	 * @param key
	 */
	public boolean deleteKey(String... key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			long ln = jedis.del(key);
			if (ln >= 0) {
				return true;
			}
		} catch (Exception e) {
			System.err.println("删除数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	/**
	 * 删除数据
	 * 
	 * @param key
	 */
	public boolean deleteKey(byte[]... key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			long ln = jedis.del(key);
			if (ln >= 0) {
				return true;
			}
		} catch (Exception e) {
			System.err.println("删除数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	/**
	 * 批量删除数据
	 * 
	 * @param pattern
	 *            （以其开头的key）
	 */
	public boolean deleteKeys(String pattern) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			Set<String> set = jedis.keys(pattern + "*");
			Iterator<String> it = set.iterator();
			int i = 0;
			while (it.hasNext()) {
				String key = it.next();
				if (jedis.exists(key)) {
					jedis.del(key);
					i++;
				}
			}
			if (i < 0) {
				return false;
			}
		} catch (Exception e) {
			System.err.println("批量删除数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 设置key生效时间
	 * 
	 * @param key
	 * @param time
	 */
	public void setExpire(String key, int time) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.expire(key, time);
			}
		} catch (Exception e) {
			System.out.println("设置key生效时间出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
	}

	/**
	 * 设置key生效时间
	 * 
	 * @param key
	 * @param time
	 */
	public static void setExpire(byte[] key, int time) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.expire(key, time);
			}
		} catch (Exception e) {
			System.out.println("设置key生效时间出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
	}

	/**
	 * 移除key的过期时间
	 * 
	 * @param key
	 */
	public void keyPersist(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.persist(key);
			}
		} catch (Exception e) {
			System.err.println("移除key的过期时间出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
	}

	/**
	 * 移除key的过期时间
	 * 
	 * @param key
	 */
	public void keyPersist(byte[] key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.persist(key);
			}
		} catch (Exception e) {
			System.err.println("移除key的过期时间出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
	}

	/**
	 * 将key重命名
	 * 
	 * @param key
	 * @param newKey
	 * @return
	 */
	public void keyRenamenx(String key, String newKey) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.renamenx(key, newKey);
			}

		} catch (Exception e) {
			System.err.println("将key重命名出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}

	}

	/**
	 * 将key重命名
	 * 
	 * @param key
	 * @param newKey
	 * @return
	 */
	public void keyRenamenx(byte[] key, byte[] newKey) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				jedis.renamenx(key, newKey);
			}

		} catch (Exception e) {
			System.out.println("将key重命名出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}

	}

	// /////////////////操作list////////////////////////////

	/**
	 * 存储list数据
	 * 
	 * @param key
	 * @param list
	 */
	public boolean SavaListValue(String key, java.util.List<String> list) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {// 追加
				for (int i = list.size() - 1; i >= 0; i--) {
					jedis.rpush(key, list.get(i));
				}
			} else {// 新增
				for (String string : list) {
					jedis.lpush(key, string);
				}
			}

		} catch (Exception e) {
			System.err.println("存储list数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 保存list对象（序列化）
	 * 
	 * @param key
	 * @param list
	 * @return
	 */
	public boolean SavaList(String key, List<Object> list) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key.getBytes())) {// 追加
				for (int i = list.size() - 1; i >= 0; i--) {
					byte[] obj = ProtostuffUtil.ObjeSerialize(list.get(i));
					jedis.rpush(key.getBytes(), obj);
				}
			} else {// 新增
				for (int i = list.size() - 1; i >= 0; i--) {
					byte[] obj = ProtostuffUtil.ObjeSerialize(list.get(i));
					jedis.lpush(key.getBytes(), obj);
				}
			}
		} catch (Exception e) {
			System.err.println("存储list数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 存储string[]数据
	 * 
	 * @param key
	 * @param list
	 */
	public boolean SavaListValue(String key, String[] values) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {// 追加
				for (int i = values.length - 1; i >= 0; i--) {
					jedis.rpush(key, values[i]);
				}
			} else {// 新增
				for (String string : values) {
					jedis.lpush(key, string);
				}
			}
		} catch (Exception e) {
			System.err.println("存储string[]数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 获取list所有数据
	 * 
	 * @param key
	 * @return
	 */
	public java.util.List<String> getListAll(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		java.util.List<String> list = new ArrayList<String>();
		try {
			if (jedis.exists(key)) {
				ListIterator<String> it = jedis.lrange(key, 0, -1)
						.listIterator();
				while (it.hasNext()) {
					it.next();
				}
				while (it.hasPrevious()) {
					list.add(it.previous());
				}
			}
		} catch (Exception e) {
			System.err.println("获取list所有数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return list;
	}

	/**
	 * 获取序列化对象
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public <T> List<T> getListAll(String key, Class<T> clazz) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		List<T> list = new ArrayList<T>();
		try {
			if (jedis.exists(key.getBytes())) {
				List<byte[]> it = jedis.lrange(key.getBytes(), 0, -1);
				for (byte[] bs : it) {
					list.add(ProtostuffUtil.deserialize(bs, clazz));
				}
			}
		} catch (Exception e) {
			System.err.println("获取list所有数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return list;
	}

	/**
	 * 获取list对应元素
	 * 
	 * @param key
	 * @param index
	 * @return
	 */
	public String getListLindex(String key, int index) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		String string = null;
		try {
			if (jedis.exists(key)) {
				string = jedis.lindex(key, index);
			}
		} catch (Exception e) {
			System.err.println("获取list对应元素出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return string;
	}

	/**
	 * 获取list中最后一个后并移除
	 * 
	 * @param key
	 * @return
	 */
	public String getListRpop(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		String string = null;
		try {
			if (jedis.exists(key)) {
				string = jedis.lpop(key);
			}
		} catch (Exception e) {
			System.err.println("获取list中最后一个后并移除出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return string;
	}

	/**
	 * 获取list中第一个后并移除
	 * 
	 * @param key
	 * @return
	 */
	public String getListLpop(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		String string = null;
		try {
			if (jedis.exists(key)) {
				string = jedis.rpop(key);
			}
		} catch (Exception e) {
			System.err.println("获取list中第一个后并移除出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return string;
	}

	/**
	 * 删除list中为value的所有元素
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean delListLrem(String key, String value) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				long ln = jedis.lrem(key, 0, value);
				if (ln >= 0) {
					return true;
				}
			}
		} catch (Exception e) {
			System.err.println("删除list中为value的所有元素出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	/**
	 * 删除list中为value的元素
	 * 
	 * @param key
	 * @param count
	 *            （ count > 0: 从头往尾移除值为 value 的元素，count为移除的个数。 count < 0:
	 *            从尾往头移除值为 value 的元素，count为移除的个数。 count = 0: 移除所有值为 value 的元素。）
	 * @param value
	 * @return
	 */
	public boolean delListLrem(String key, int count, String value) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				long ln = jedis.lrem(key, count, value);
				if (ln >= 0) {
					return true;
				}
			}
		} catch (Exception e) {
			System.err.println("删除list中为value的元素出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	/**
	 * 删除list中为obj的元素
	 * 
	 * @param key
	 * @param count
	 *            （ count > 0: 从头往尾移除值为 value 的元素，count为移除的个数。 count < 0:
	 *            从尾往头移除值为 value 的元素，count为移除的个数。 count = 0: 移除所有值为 value 的元素。）
	 * @param obj
	 * @return
	 */
	public boolean delListLrem(String key, int count, Object obj) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key.getBytes())) {
				byte[] value = ProtostuffUtil.ObjeSerialize(obj);
				long ln = jedis.lrem(key.getBytes(), count, value);
				if (ln > 0) {
					return true;
				}
			}
		} catch (Exception e) {
			System.err.println("删除list中为value的元素出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	// ///////////////操作map////////////////////////////
	/**
	 * 存储map数据
	 * 
	 * @param key
	 * @param map
	 */
	public boolean SaveMap(String key, Map<String, String> map) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			jedis.hmset(key, map);
		} catch (Exception e) {
			System.err.println("存储map数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 存储map数据
	 * 
	 * @param key
	 * @param mapKey
	 * @param mapValue
	 */
	public boolean SaveMap(String key, String mapKey, String mapValue) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			jedis.hset(key, mapKey, mapValue);
		} catch (Exception e) {
			System.err.println("存储map数据出错:" + e.getMessage());
			return false;
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 获取map中全部的域和值
	 * 
	 * @param key
	 * @return
	 */
	public Map<String, String> getMapValue(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		Map<String, String> map = new HashMap<String, String>();
		try {
			if (jedis.exists(key)) {
				map = jedis.hgetAll(key);
			}
		} catch (Exception e) {
			System.err.println("获取map中全部的域和值出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return map;
	}

	/**
	 * 获取指定map中key对应的value
	 * 
	 * @param key
	 * @param mapKey
	 * @return
	 */
	public java.util.List<String> getMapHget(String key, String... mapKey) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		java.util.List<String> list = new ArrayList<String>();
		try {
			if (jedis.exists(key)) {
				list = jedis.hmget(key, mapKey);
			}
		} catch (Exception e) {
			System.err.println("获取指定map中key对应的value出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return list;
	}

	/**
	 * 删除map指定的值
	 * 
	 * @param key
	 * @param mapKey
	 * @return
	 */
	public boolean delMapKey(String key, String... mapKey) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				long ln = jedis.hdel(key, mapKey);
				if (ln >= 0) {
					return true;
				}
			}
		} catch (Exception e) {
			System.err.println("删除map中数据错误:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	// /////////////操作set///////////////////////

	/**
	 * 存储set数据
	 * 
	 * @param key
	 * @param values
	 * @return
	 */
	public boolean SavaSet(String key, String... values) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			long ln = jedis.sadd(key, values);
			if (ln >= 0) {
				return true;
			}
		} catch (Exception e) {
			System.err.println("存储set数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	/**
	 * 获取set数据所有数据
	 * 
	 * @param key
	 * @return
	 */
	public Set<String> getSetAll(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		Set<String> set = new HashSet<String>();
		try {
			if (jedis.exists(key)) {
				set = jedis.smembers(key);
			}
		} catch (Exception e) {
			System.err.println("获取所有set数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return set;
	}

	/**
	 * 删除set中数据
	 * 
	 * @param key
	 * @param values
	 *            （set中数据）
	 * @return
	 */
	public boolean delSet(String key, String... values) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			if (jedis.exists(key)) {
				long ln = jedis.srem(key, values);
				if (ln >= 0) {
					return true;
				}
			}
		} catch (Exception e) {
			System.err.println("删除set数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return false;
	}

	/**
	 * 判断value是否在set中
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean existsSet(String key, String value) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		boolean flag = false;
		try {
			flag = jedis.sismember(key, value);
		} catch (Exception e) {
			System.err.println("判断set中数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return flag;
	}

	/**
	 * 存储对象
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 */
	public <T> boolean SaveObject(String key, T obj) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		byte[] keyByte = key.getBytes();
		byte[] valueByte = ProtostuffUtil.ObjeSerialize(obj);
		try {
			jedis.set(keyByte, valueByte);
		} catch (Exception e) {
			System.err.println("存储对象数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 获取存储对象
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 */
	public <T> T getObject(String key, Class<T> clazz) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		byte[] keyByte = key.getBytes();
		byte[] objByte = null;
		T result = null;
		try {
			if (jedis.exists(keyByte)) {
				objByte = jedis.get(keyByte);
				result = ProtostuffUtil.deserialize(objByte, clazz);
			}
		} catch (Exception e) {
			System.err.println("获取存储对象数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return result;
	}

	/**
	 * 存储list<T>对象
	 * 
	 * @param key
	 * @param list
	 * @return
	 */
	public <T> boolean SaveListObject(String key, java.util.List<T> list) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		byte[] keyByte = key.getBytes();
		byte[] listByte = ProtostuffUtil.serializeList(list);
		try {
			jedis.set(keyByte, listByte);
		} catch (Exception e) {
			System.err.println("存储对象list数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return true;
	}

	/**
	 * 获取存储list<T>对象
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 */
	public <T> java.util.List<T> getListObject(String key, Class<T> clazz) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		java.util.List<T> list = new ArrayList<T>();
		byte[] keyByte = key.getBytes();
		byte[] jedisByte = null;
		try {
			if (jedis.exists(keyByte)) {
				jedisByte = jedis.get(keyByte);
				list = ProtostuffUtil.deserializeList(jedisByte, clazz);
			}
		} catch (Exception e) {
			System.err.println("存储对象list数据出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return list;
	}

	/**
	 * 自增
	 * 
	 * @param key
	 * @return
	 */
	public long incr(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			return jedis.incr(key);
		} catch (Exception e) {
			System.err.println("自增出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return 0;
	}

	/**
	 * 自减
	 * 
	 * @param key
	 * @return
	 */
	public long decr(String key) {
		Jedis jedis = RedisPoolMap.init().getJedis();
		try {
			return jedis.decr(key);
		} catch (Exception e) {
			System.err.println("自增出错:" + e.getMessage());
		} finally {
			RedisPoolMap.init().jedisRemove();
		}
		return 0;
	}
}
